package com.ding.email.service.impl;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ding.email.entity.MailInfo;
import com.ding.email.service.ISendMsgHandle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Map;
import java.util.Set;

/**
 * @author dingfeng
 * @version 1.0
 * @DEC
 * @date 2022-03-30 9:00
 */
@Slf4j
@Component
public class EmailSendMsgHandle implements ISendMsgHandle, InitializingBean {
    /**
     * 邮件发送核心类
     */
    public static JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();

    @Value(value = "${email.account}")
    private String emailFrom;

    @Value("${email.host}")
    private String host;

    @Value("${email.account}")
    private String account;

    @Value("${email.password}")
    private String password;

    @Value("${email.port:-1}")
    private Integer port;

    @Override
    public void afterPropertiesSet() throws Exception {
        javaMailSender.setHost(host);
        javaMailSender.setPassword(password);
        javaMailSender.setUsername(account);
        javaMailSender.setPort(port);
    }

    @Override
    public void sendSimpleTextEmail(MailInfo mailInfo) {

        SimpleMailMessage mailMessage = new SimpleMailMessage();
        //发件人
        mailMessage.setFrom(emailFrom);
        //接收人
        mailMessage.setTo(mailInfo.getReceiver());
        //邮件主题
        mailMessage.setSubject(mailInfo.getSubject());
        //邮件抄送
        if (ObjectUtil.isNotNull(mailInfo.getCc())) {
            mailMessage.setCc(mailInfo.getCc());
        }
        //邮件内容
        mailMessage.setText(mailInfo.getContent());
        try {
            //发送邮件
            javaMailSender.send(mailMessage);
        } catch (Exception e) {
            log.error("邮件发送失败:{}", e.getMessage());
        }
    }

    @Override
    public void sendHtmlEmail(MailInfo mailInfo, boolean html) {
        MimeMessage mimeMailMessage = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = setBaseInfo(mailInfo, mimeMailMessage);
            //邮件内容
            mimeMessageHelper.setText(mailInfo.getContent(), html);
            javaMailSender.send(mimeMailMessage);
        } catch (Exception e) {
            log.error("邮件发送失败:{}", e.getMessage());
        }

    }

    @Override
    public void sendEnclosureEmail(MailInfo mailInfo) {
        try {
            MimeMessage mimeMailMessage = javaMailSender.createMimeMessage();

            setBaseInfo(mailInfo, mimeMailMessage);

            MimeMultipart allMultipart = new MimeMultipart();

            //创建代表邮件正文和附件的各个MimeBodyPart对象
            MimeBodyPart contentPart = createContent(mailInfo.getContent(), mailInfo.getImageMap());
            allMultipart.addBodyPart(contentPart);

            //创建用于组合邮件正文和附件的MimeMultipart对象
            if (ObjectUtil.isNotNull(mailInfo.getAttachFileNames())) {
                for (int i = 0; i < mailInfo.getAttachFileNames().length; i++) {
                    allMultipart.addBodyPart(createAttachment(mailInfo.getAttachFileNames()[i]));
                }
            }
            //设置整个邮件内容为最终组合出的MimeMultipart对象
            mimeMailMessage.setContent(allMultipart);
            mimeMailMessage.saveChanges();

            javaMailSender.send(mimeMailMessage);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("邮件发送失败:{}", e.getMessage());
        }
    }

    /**
     * 设置基础信息
     *
     * @param mailInfo        邮件信息实体
     * @param mimeMailMessage 复合邮件
     * @return MimeBodyPart
     */
    private MimeMessageHelper setBaseInfo(MailInfo mailInfo, MimeMessage mimeMailMessage) throws MessagingException {
        //true 表示需要创建一个multipart message
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMailMessage, true, CharsetUtil.UTF_8);
        //发件人
        mimeMessageHelper.setFrom(emailFrom);
        //接收人
        mimeMessageHelper.setTo(mailInfo.getReceiver());
        //邮件主题
        mimeMessageHelper.setSubject(mailInfo.getSubject());
        //邮件抄送
        if (ObjectUtil.isNotNull(mailInfo.getCc())) {
            mimeMessageHelper.setCc(mailInfo.getCc());
        }
        //设置显示的发件时间
        mimeMessageHelper.setSentDate(new Date());
        return mimeMessageHelper;
    }

    /**
     * 功能描述：邮件附件
     *
     * @param filename 文件路径
     * @return MimeBodyPart
     */
    private MimeBodyPart createAttachment(String filename) throws Exception {
        //创建保存附件的MimeBodyPart对象，并加入附件内容和相应的信息
        MimeBodyPart attachPart = new MimeBodyPart();
        FileDataSource fsd = new FileDataSource(filename);

        attachPart.setDataHandler(new DataHandler(fsd));
        attachPart.setFileName(fsd.getName());
        return attachPart;
    }

    /**
     * 功能描述：文本内容
     *
     * @param body html格式的文本内容
     * @return MimeBodyPart
     */
    private MimeBodyPart createContent(String body) throws Exception {
        //创建代表组合Mime消息的MimeMultipart对象，将该MimeMultipart对象保存到MimeBodyPart对象
        MimeBodyPart contentPart = new MimeBodyPart();
        MimeMultipart contentMultipart = new MimeMultipart("related");

        //创建用于保存HTML正文的MimeBodyPart对象，并将它保存到MimeMultipart中
        MimeBodyPart htmlBodyPart = new MimeBodyPart();
        htmlBodyPart.setContent(body, "text/html;charset=UTF-8");
        contentMultipart.addBodyPart(htmlBodyPart);

        //将MimeMultipart对象保存到MimeBodyPart对象
        contentPart.setContent(contentMultipart);
        return contentPart;
    }

    /**
     * 功能描述：文本内嵌图片
     *
     * @param body html格式的文本内容
     * @param map  图片集合
     * @return {@link MimeBodyPart}
     */
    private MimeBodyPart createContent(String body, Map<String, String> map) throws Exception {
        //创建代表组合Mime消息的MimeMultipart对象，将该MimeMultipart对象保存到MimeBodyPart对象
        MimeBodyPart contentPart = new MimeBodyPart();
        MimeMultipart contentMultipart = new MimeMultipart("related");

        //创建用于保存HTML正文的MimeBodyPart对象，并将它保存到MimeMultipart中
        MimeBodyPart htmlBodyPart = new MimeBodyPart();
        htmlBodyPart.setContent(body, "text/html;charset=UTF-8");
        contentMultipart.addBodyPart(htmlBodyPart);

        if (map != null && map.size() > 0) {
            Set<Map.Entry<String, String>> set = map.entrySet();
            for (Map.Entry<String, String> entry : set) {
                //创建用于保存图片的MimeBodyPart对象，并将它保存到MimeMultipart中
                MimeBodyPart gifBodyPart = new MimeBodyPart();
                FileDataSource fds = new FileDataSource(entry.getValue());
                //图片所在的目录的绝对路径
                gifBodyPart.setDataHandler(new DataHandler(fds));
                //cid的值
                gifBodyPart.setContentID(entry.getKey());
                contentMultipart.addBodyPart(gifBodyPart);
            }
        }

        //将MimeMultipart对象保存到MimeBodyPart对象
        contentPart.setContent(contentMultipart);
        return contentPart;
    }




}
